package accuracy;
import java.math.BigDecimal;

/**
 * 使用BigDecimal进行精度运算.
 *
 * 该类依赖于java BigDecimal,主要使用了下列4个方法:
 * 
 * {@code BigDecimal.subtract(n2);}
 * {@code BigDecimal.multiply(n2);}
 * {@code BigDecimal.divide(n1);}
 * {@code BigDecimal.add(n2);}
 * 
 * @see	java.math.BigDecimal
 * @author guanweichen
 * @version Jul 13, 2011
 */
public class CalculationUtils {
	
	/**
	 * num1 + num2
	 * 
	 * @param num1
	 * @param num2
	 * @exception NullPointerException 当传入的数字为 null
	 * @return 计算后的值
	 */
	public static BigDecimal addition(Number num1, Number num2) {
		return calculation(num1, num2, CalculationMode.ADDITION);
	}
	/**
	 * num1 * num2
	 * 
	 * @param num1
	 * @param num2
	 * @exception NullPointerException 当传入的数字为 null
	 * @return 计算后的值
	 */
	public static BigDecimal multiply(Number num1, Number num2) {
		return calculation(num1, num2, CalculationMode.MULTIPLICATION);
	}
	/**
	 * num1 / num2
	 * 
	 * @param num1
	 * @param num2
	 * @exception NullPointerException 当传入的数字为 null
	 * @return 计算后的值
	 */
	public static BigDecimal division(Number num1, Number num2) {
		return calculation(num1, num2, CalculationMode.DIVISION);
	}
	/**
	 * num1 - num2
	 * 
	 * @param num1
	 * @param num2
	 * @exception NullPointerException 当传入的数字为 null
	 * @return 计算后的值
	 */
	public static BigDecimal subtract(Number num1, Number num2) {
		return calculation(num1, num2, CalculationMode.SUBTRACTION);
	}
	
	private static BigDecimal calculation(Number num1, Number num2, CalculationMode type) {
		if( num1 == null || num2 == null ){
			throw new NullPointerException("Number is null!");
		}
		BigDecimal n1 = new BigDecimal(num1.toString());
		BigDecimal n2 = new BigDecimal(num2.toString());
		if (type == CalculationMode.ADDITION) {
			return n1.add(n2);
		} else if (type == CalculationMode.SUBTRACTION) {
			return n1.subtract(n2);
		} else if (type == CalculationMode.MULTIPLICATION) {
			return n1.multiply(n2);
		} else if (type == CalculationMode.DIVISION) {
			return n1.divide(n1);
		}
		return null;
	}
	
	private enum CalculationMode {
		ADDITION,SUBTRACTION,MULTIPLICATION,DIVISION;
	}
}
